#ifndef HEAP_TIMER_H
#define HEAP_TIMER_H

#include <time.h>
#include <chrono> // C++11 定时器
#include <functional>
#include <unordered_map>
#include <vector>

typedef std::function<void()> TimeoutCallBack;
typedef std::chrono::high_resolution_clock Clock;
typedef std::chrono::milliseconds MS;
typedef Clock::time_point TimeStamp;


// 最小堆定时器中的一个节点
struct TimerNode {
    int id; // 标识符
    TimeStamp expires; // 超时时间
    TimeoutCallBack cb; // 回调函数
    // 定义比较函数，因为要排序，放在最小堆中
    bool operator<(const TimerNode& t) {
        return expires < t.expires;
    } 
};

class HeapTimer {
public:
    HeapTimer();
    ~HeapTimer();
    void Adjust(int id, int timeout); // 调整指定id的节点,先改变节点的expires=now+timeout，再调整堆siftdown
    void Dowork(int id); // 删除指定节点，并触发回调函数
    void Tick(); // 清除超时节点
    int GetNextTick(); // 获取堆顶计时器的超时时间
    void Add(int id, int timeout, const TimeoutCallBack& cb); // 添加节点
private:
    void pop(); // 删除堆顶元素
    void Delete(size_t index); // 删除指定位置的节点
    bool SiftDown(size_t index, size_t n); // 下标为index的节点向下调整,n代表调整的范围
    void SiftUp(size_t index); // 下标为index的节点向上调整,n代表调整的范围
    void SwapNode(size_t i, size_t j);
private:
    std::vector<TimerNode> m_heap; // 最小堆定时器
    std::unordered_map<int, size_t> m_ref; // 键为定时器id，值为m_heap中位置
};




#endif